require("./dialog.css");

var $ = require("./jquery");
var Popup = require("./popup");
var defaults = require("./config");
var _count = 0;
var _expando = new Date() - 0; // Date.now()
var _isIE6 = !("minWidth" in $("html")[0].style);
var _isMobile =
    ("createTouch" in document && !("onmousemove" in document)) ||
    /(iPhone|iPad|iPod)/i.test(navigator.userAgent);
var _isFixed = !_isIE6 && !_isMobile;

var artDialog = function(options, ok, cancel) {
    var originalOptions = (options = options || {});

    if (typeof options === "string" || options.nodeType === 1) {
        options = { content: options, fixed: !_isMobile };
    }

    options = $.extend(true, {}, artDialog.defaults, options);
    options.original = originalOptions;

    var id = (options.id = options.id || _expando + _count);
    var api = artDialog.get(id);

    // 如果存在同名的对话框对象，则直接返回
    if (api) {
        return api.focus();
    }

    // 目前主流移动设备对fixed支持不好，禁用此特性
    if (!_isFixed) {
        options.fixed = false;
    }

    // 快捷关闭支持：点击对话框外快速关闭对话框
    if (options.quickClose) {
        options.modal = true;
        options.backdropOpacity = 0;
    }

    // 按钮组
    if (!$.isArray(options.button)) {
        options.button = [];
    }

    // 取消按钮
    if (cancel !== undefined) {
        options.cancel = cancel;
    }

    if (options.cancel) {
        options.button.push({
            id: "cancel",
            value: options.cancelValue,
            callback: options.cancel,
            display: options.cancelDisplay
        });
    }

    // 确定按钮
    if (ok !== undefined) {
        options.ok = ok;
    }

    if (options.ok) {
        options.button.push({
            id: "ok",
            value: options.okValue,
            callback: options.ok,
            autofocus: true
        });
    }

    return (artDialog.list[id] = new artDialog.create(options));
};

var popup = function() {};
popup.prototype = Popup.prototype;
var prototype = (artDialog.prototype = new popup());

artDialog.create = function(options) {
    var that = this;

    $.extend(this, new Popup());

    var originalOptions = options.original;
    var $popup = $(this.node).html(options.innerHTML);
    var $backdrop = $(this.backdrop);

    this.options = options;
    this._popup = $popup;

    $.each(options, function(name, value) {
        if (typeof that[name] === "function") {
            that[name](value);
        } else {
            that[name] = value;
        }
    });

    // 更新 zIndex 全局配置
    if (options.zIndex) {
        Popup.zIndex = options.zIndex;
    }

    // 设置 ARIA 信息
    $popup.attr({
        "aria-labelledby": this._$("title")
            .attr("id", "title:" + this.id)
            .attr("id"),
        "aria-describedby": this._$("content")
            .attr("id", "content:" + this.id)
            .attr("id")
    });

    // 关闭按钮
    this._$("close")
        .css("display", this.cancel === false ? "none" : "")
        .attr("title", this.cancelValue)
        .on("click", function(event) {
            that._trigger("cancel");
            event.preventDefault();
        });

    // 添加视觉参数
    this._$("dialog").addClass(this.skin);
    this._$("body").css("padding", this.padding);

    // 点击任意空白处关闭对话框
    if (options.quickClose) {
        $backdrop.on(
            "onmousedown" in document ? "mousedown" : "click",
            function() {
                that._trigger("cancel");
                return false; // 阻止抢夺焦点
            }
        );
    }

    // 遮罩设置
    this.addEventListener("show", function() {
        $backdrop
            .css({
                opacity: 0,
                background: options.backdropBackground
            })
            .animate({ opacity: options.backdropOpacity }, 150);
    });

    // ESC 快捷键关闭对话框
    this._esc = function(event) {
        var target = event.target;
        var nodeName = target.nodeName;
        var rinput = /^input|textarea$/i;
        var isTop = Popup.current === that;
        var keyCode = event.keyCode;

        // 避免输入状态中 ESC 误操作关闭
        if (!isTop || (rinput.test(nodeName) && target.type !== "button")) {
            return;
        }

        if (keyCode === 27) {
            that._trigger("cancel");
        }
    };

    $(document).on("keydown", this._esc);
    this.addEventListener("remove", function() {
        $(document).off("keydown", this._esc);
        delete artDialog.list[this.id];
    });

    _count++;

    artDialog.oncreate(this);

    return this;
};

artDialog.create.prototype = prototype;

$.extend(prototype, {
    /**
     * 显示对话框
     * @name artDialog.prototype.show
     * @param   {HTMLElement Object, Event Object}  指定位置（可选）
     */

    /**
     * 显示对话框（模态）
     * @name artDialog.prototype.showModal
     * @param   {HTMLElement Object, Event Object}  指定位置（可选）
     */

    /**
     * 关闭对话框
     * @name artDialog.prototype.close
     * @param   {String, Number}    返回值，可被 onclose 事件收取（可选）
     */

    /**
     * 销毁对话框
     * @name artDialog.prototype.remove
     */

    /**
     * 重置对话框位置
     * @name artDialog.prototype.reset
     */

    /**
     * 让对话框聚焦（同时置顶）
     * @name artDialog.prototype.focus
     */

    /**
     * 让对话框失焦（同时置顶）
     * @name artDialog.prototype.blur
     */

    /**
     * 添加事件
     * @param   {String}    事件类型
     * @param   {Function}  监听函数
     * @name artDialog.prototype.addEventListener
     */

    /**
     * 删除事件
     * @param   {String}    事件类型
     * @param   {Function}  监听函数
     * @name artDialog.prototype.removeEventListener
     */

    /**
     * 对话框显示事件，在 show()、showModal() 执行
     * @name artDialog.prototype.onshow
     * @event
     */

    /**
     * 关闭事件，在 close() 执行
     * @name artDialog.prototype.onclose
     * @event
     */

    /**
     * 销毁前事件，在 remove() 前执行
     * @name artDialog.prototype.onbeforeremove
     * @event
     */

    /**
     * 销毁事件，在 remove() 执行
     * @name artDialog.prototype.onremove
     * @event
     */

    /**
     * 重置事件，在 reset() 执行
     * @name artDialog.prototype.onreset
     * @event
     */

    /**
     * 焦点事件，在 foucs() 执行
     * @name artDialog.prototype.onfocus
     * @event
     */

    /**
     * 失焦事件，在 blur() 执行
     * @name artDialog.prototype.onblur
     * @event
     */

    /**
     * 设置内容
     * @param    {String, HTMLElement}   内容
     */
    content: function(html) {
        var $content = this._$("content");

        // HTMLElement
        if (typeof html === "object") {
            html = $(html);
            $content.empty("").append(html.show());
            this.addEventListener("beforeremove", function() {
                $("body").append(html.hide());
            });
            // String
        } else {
            $content.html(html);
        }

        return this.reset();
    },

    /**
     * 设置标题
     * @param    {String}   标题内容
     */
    title: function(text) {
        this._$("title").text(text);
        this._$("header")[text ? "show" : "hide"]();
        return this;
    },

    /** 设置宽度 */
    width: function(value) {
        this._$("content").css("width", value);
        return this.reset();
    },

    /** 设置高度 */
    height: function(value) {
        this._$("content").css("height", value);
        return this.reset();
    },

    /**
     * 设置按钮组
     * @param   {Array, String}
     * Options: value, callback, autofocus, disabled
     */
    button: function(args) {
        args = args || [];
        var that = this;
        var html = "";
        var number = 0;
        this.callbacks = {};

        if (typeof args === "string") {
            html = args;
            number++;
        } else {
            $.each(args, function(i, val) {
                var id = (val.id = val.id || val.value);
                var style = "";
                that.callbacks[id] = val.callback;

                if (val.display === false) {
                    style = ' style="display:none"';
                } else {
                    number++;
                }

                html +=
                    "<button" +
                    ' type="button"' +
                    ' i-id="' +
                    id +
                    '"' +
                    style +
                    (val.disabled ? " disabled" : "") +
                    (val.autofocus ?
                        ' autofocus class="ui-dialog-autofocus"' :
                        "") +
                    ">" +
                    val.value +
                    "</button>";

                that._$("button").on("click", "[i-id=" + id + "]", function(
                    event
                ) {
                    var $this = $(this);
                    if (!$this.attr("disabled")) {
                        // IE BUG
                        that._trigger(id);
                    }

                    event.preventDefault();
                });
            });
        }

        this._$("button").html(html);
        this._$("footer")[number ? "show" : "hide"]();

        return this;
    },

    statusbar: function(html) {
        this._$("statusbar")
            .html(html)[html ? "show" : "hide"]();

        return this;
    },

    _$: function(i) {
        return this._popup.find("[i=" + i + "]");
    },

    // 触发按钮回调函数
    _trigger: function(id) {
        var fn = this.callbacks[id];

        return typeof fn !== "function" || fn.call(this) !== false ?
            this.close().remove() :
            this;
    }
});

artDialog.oncreate = $.noop;

/** 获取最顶层的对话框API */
artDialog.getCurrent = function() {
    return Popup.current;
};

/**
 * 根据 ID 获取某对话框 API
 * @param    {String}    对话框 ID
 * @return   {Object}    对话框 API (实例)
 */
artDialog.get = function(id) {
    return id === undefined ? artDialog.list : artDialog.list[id];
};

artDialog.list = {};

/**
 * 默认配置
 */
artDialog.defaults = defaults;

module.exports = artDialog;